package com.lmh.friend.manager;

import cn.hutool.core.collection.CollectionUtil;
import com.github.pagehelper.PageHelper;
import com.lmh.common.core.constants.CacheConstants;
import com.lmh.common.core.domain.dto.PageQueryDTO;
import com.lmh.common.redis.service.RedisService;
import com.lmh.friend.domain.message.vo.MessageTextVO;
import com.lmh.friend.mapper.message.MessageMapper;
import com.lmh.friend.mapper.message.MessageTextMapper;
import org.jetbrains.annotations.Nullable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Component
public class MessageCacheManager {
    @Autowired
    private RedisService redisService;

    @Autowired
    private MessageTextMapper messageTextMapper;

    @Autowired
    private MessageMapper messageMapper;

    public Long getListSize(Long userId) {
        String userMessageListKey = getUserMessageListKey(userId);
        return redisService.getListSize(userMessageListKey);
    }

    public void refreshCache(Long userId) {
        List<MessageTextVO> messageTextVOList = messageTextMapper.selectUserMsgList(userId);
        if (CollectionUtil.isEmpty(messageTextVOList)) {
            return;
        }
        List<Long> textIdList = messageTextVOList.stream().map(MessageTextVO::getTextId)
                                        .collect(Collectors.toList());
        String userMessageListKey = getUserMessageListKey(userId);
        redisService.rightPushAll(userMessageListKey,textIdList);
        Map<String, MessageTextVO> messageTextVOMap = new HashMap<>();
        for (MessageTextVO messageTextVO : messageTextVOList) {
            messageTextVOMap.put(getMsgDetailKey(messageTextVO.getTextId()),messageTextVO);
        }
        redisService.multiSet(messageTextVOMap);
    }

    public List<MessageTextVO> getMsgTextVOList(PageQueryDTO dto, Long userId) {
        int start = (dto.getPageNum() - 1) * dto.getPageSize();
        int end = start + dto.getPageSize() - 1;
        String userMsgListKey = getUserMessageListKey(userId);
        List<Long> msgTextIdList = redisService.getCacheListByRange(userMsgListKey,start,end, Long.class);
        List<MessageTextVO> messageTextVOList = assembleMsgTextVOList(msgTextIdList);
        if (CollectionUtil.isEmpty(messageTextVOList)) {
            messageTextVOList = getMsgTextVOListByDB(dto, userId);
            refreshCache(userId);
        }
        return messageTextVOList;
    }

    public boolean deleteCache(Long textId, Long userId) {
        String userMsgListKey = getUserMessageListKey(userId);
        return redisService.removeForList(userMsgListKey,textId) != 0
                && redisService.deleteObject(getMsgDetailKey(textId));
    }

    private List<MessageTextVO> assembleMsgTextVOList(List<Long> msgTextIdList) {
        if (CollectionUtil.isEmpty(msgTextIdList)) {
            return null;
        }
        List<String> msgTextDetailKeyList = new ArrayList<>();
        for (Long msgTextId : msgTextIdList) {
            msgTextDetailKeyList.add(getMsgDetailKey(msgTextId));
        }
        List<MessageTextVO> messageTextVOList = redisService.multiGet(msgTextDetailKeyList, MessageTextVO.class);
        if (CollectionUtil.isEmpty(messageTextVOList) || messageTextVOList.size() != msgTextIdList.size()) {
            //说明redis中数据有问题 从数据库中查数据并且重新刷新缓存
            return null;
        }
        return messageTextVOList;
    }


    private List<MessageTextVO> getMsgTextVOListByDB(PageQueryDTO dto, Long userId) {
        PageHelper.startPage(dto.getPageNum(), dto.getPageSize());
        return messageTextMapper.selectUserMsgList(userId);
    }

    private String getMsgDetailKey(Long textId) {
        return CacheConstants.MESSAGE_DETAIL + textId;
    }

    private String getUserMessageListKey(Long userId) {
        return CacheConstants.USER_MESSAGE_LIST + userId;
    }
}
